package com.goods.shop.service.card;

import com.goods.shop.service.AbstractService;
import com.goods.shop.service.model.card.CardModel;
import com.goods.shop.util.TimeUtils;
import org.springframework.beans.BeanUtils;

import java.io.*;
import java.time.LocalDateTime;
import java.util.*;

public class CardServiceImpl extends AbstractService implements CardService {
    String[] passport = new String[]{"N", "M", "BA", "TK", "USA", "A", "MP"};
    String[] foreignCards = new String[]{"AUS", "USA", "DEU", "USA", "JPN", "AUS", "KOR", "USA", "UAS"};
    String[] taiWanCard = new String[]{"B", "D", "", "(D)", "(B)"};
    String[] plaCard = new String[]{"(海文字第)", "(空文字第)", ""};
    String[] THL = new String[]{"830000", "810000", "820000"};
    Random random = new Random();
    LocalDateTime time = LocalDateTime.now();
    //生成护照--7位
    public String generateHuZhao() {
        StringBuilder generater = new StringBuilder();
        int length = passport.length;
        Random random = new Random();
        int index = random.nextInt(length);
        generater.append(passport[index]);
        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(7);
        generater.append(millis);
        return generater.toString();
    }

    //17 外国人永久居留身份证--12位数字
    public String generateForeignCard() {
        StringBuilder generater = new StringBuilder();
        int length = foreignCards.length;
        Random random = new Random();
        int index = random.nextInt(length);
        generater.append(foreignCards[index]);
        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(2);
        generater.append(millis);
        return generater.toString();
    }

    //中国护照
    public String generateChinesePassportCard() {
        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(5);
        return millis;
    }

    //香港通行证
    public String generateHKCard() {
        StringBuilder generater = new StringBuilder();
        generater.append("H0");
        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(5);
        generater.append(millis);
        return generater.toString();
    }

    //澳门通行证
    public String generateAoMenCard() {
        StringBuilder generater = new StringBuilder();
        generater.append("MO");
        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(5);
        generater.append(millis);
        return generater.toString();
    }

    //台湾通行证或有效旅行证件
    public String generateTaiWanCard() {
        StringBuilder generater = new StringBuilder();
        int length = taiWanCard.length;
        Random random = new Random();
        int index = random.nextInt(length);

        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(4);

        generater.append(millis);
        generater.append(taiWanCard[index]);
        return generater.toString();
    }

    //其他 固定成7位数
    public String generateOtherCard() {
        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(7);
        return millis;
    }

    //03 军官证
    public String generatePLACard() {
        StringBuilder generater = new StringBuilder();
        int length = plaCard.length;
        Random random = new Random();
        int index = random.nextInt(length);

        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(8);

        generater.append(plaCard[index]);
        generater.append(millis);
        int num = Integer.valueOf(millis);
        if (num % 2 == 0) generater.append("号");
        return generater.toString();
    }

    //台湾居民居住证\香港居民居住证\澳门居民居住证 TODO
    public String generateTHAResidentCard() {
        StringBuilder generater = new StringBuilder();
        int length = THL.length;
        Random random = new Random();
        int index = random.nextInt(length);

        String millis = String.valueOf(System.nanoTime());
        millis = millis.substring(10);
        generater.append(THL[index]);
        generater.append(randomBirthday());
        generater.append(millis);
        return generater.toString();
    }

    public String generateIDCards() {
        StringBuilder generater = new StringBuilder();
        generater.append(this.randomAreaCode());
        generater.append(this.randomBirthday());
        generater.append(this.randomCode());
//        generater.replace(generater.length() - 1, generater.length(), sex);
        generater.append(this.calcTrailingNumber(generater.toString().toCharArray()));
        return generater.toString();
    }

    public int randomAreaCode() {
        int areaSize = IDCards.getAreas().size();
        int index = (int) (Math.random() * areaSize);
        Collection<Integer> values = IDCards.getAreas().values();
        Iterator<Integer> it = values.iterator();
        int i = 0;
        int code = 0;
        while (i < index && it.hasNext()) {
            i++;
            code = it.next();
        }
        return code;
    }

    public String randomBirthday() {
        Calendar birthday = Calendar.getInstance();
        birthday.set(Calendar.YEAR, (int) (Math.random() * 60) + 1950);
        birthday.set(Calendar.MONTH, (int) (Math.random() * 12));
        birthday.set(Calendar.DATE, (int) (Math.random() * 31));

        StringBuilder builder = new StringBuilder();
        builder.append(birthday.get(Calendar.YEAR));
        long month = birthday.get(Calendar.MONTH) + 1L;
        if (month < 10) {
            builder.append("0");
        }
        builder.append(month);
        long date = birthday.get(Calendar.DATE);
        if (date < 10) {
            builder.append("0");
        }
        builder.append(date);
        return builder.toString();
    }

    public char calcTrailingNumber(char[] chars) {
        if (chars.length < 17) {
            return ' ';
        }
        int[] c = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char[] r = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
        int[] n = new int[17];
        int result = 0;
        for (int i = 0; i < n.length; i++) {
            n[i] = Integer.parseInt(chars[i] + "");
        }
        for (int i = 0; i < n.length; i++) {
            result += c[i] * n[i];
        }
        return r[result % 11];
    }

    public String randomCode() {
        int code = (int) (Math.random() * 1000);
        if (code < 10) {
            return "00" + code;
        } else if (code < 100) {
            return "0" + code;
        } else {
            return "" + code;
        }
    }
    public String transSrc(int num) {
       int code=num%7;
       switch(code){
           case 1:
               return "WEIXIN";
           case 2:
               return "ZHIFUBAO";
           case 3:
                   return "YL";
           case 4:
               return "MEITUAN";
           case 5:
               return "JDJR";
           default:
               return "OTHER";
       }

    }
    public String campId(int num) {
        int code=num%5;
        return "00"+code;
    }
    public String generateNumCards(int num) {
        int mod = num % 100;
        String cardNo = "";
        if (mod <= 80) {
            cardNo = this.generateIDCards();//身份证
        } else if (mod == 81 || mod == 82) {
            cardNo = this.generateHuZhao();//生成护照
        } else if (mod == 83 || mod == 84) {
            cardNo = this.generateForeignCard();//17 外国人永久居留身份证
        } else if (mod == 85 || mod == 86) {
            cardNo = this.generateChinesePassportCard();//中国护照
        } else if (mod == 87 || mod == 88) {
            cardNo = this.generateHKCard(); //香港通行证
        } else if (mod == 89 || mod == 90) {
            cardNo = this.generateAoMenCard();//澳门通行证
        } else if (mod == 91 || mod == 92) {
            cardNo = this.generateTaiWanCard(); //台湾通行证或有效旅行证件
        } else if (mod == 93 || mod == 94) {
            cardNo = this.generateOtherCard(); //其他 固定成7位数
        } else if (mod == 95 || mod == 96||mod == 97) {
            cardNo = this.generatePLACard();//03 军官证
        } else {
            cardNo = this.generateTHAResidentCard();//台湾居民居住证\香港居民居住证\澳门居民居住证 TODO
        }
        return cardNo;
    }


    public String generateAcctSQL(CardModel cardModel) {
//        StringBuilder sql = new StringBuilder("INSERT INTO `tbl_rights_acct` VALUES ('");
        StringBuilder sql = new StringBuilder("'");
        sql.append(cardModel.getAcctId()).append("','");//ID
        sql.append(cardModel.getCustId()).append("','");//CUSTID
        sql.append(cardModel.getRightsId()).append("','");//RIGHTSID
        sql.append(cardModel.getOperval()).append("','");//BALANCE
        sql.append(cardModel.getEndDate()).append("','");//ENDDATE
        sql.append(cardModel.getCreateDate()).append("','");//CREATEDATE
        sql.append(cardModel.getCreateTime()).append("','");//CREATETIME
        sql.append(cardModel.getUpdateDate()).append("','");//UPDATEDATE
        sql.append(cardModel.getUpdateTime()).append("','");//UPDATETIME
//        sql.append(cardModel.getOrgCode()).append("');");//ORGCODE
        sql.append(cardModel.getOrgCode()).append("'");//ORGCODE
        return sql.toString();
    }
    public String generateDetailSQL(CardModel cardModel) {
//        StringBuilder sql=new StringBuilder("INSERT INTO `tbl_rights_detail` VALUES ('");
        StringBuilder sql = new StringBuilder("'");
        sql.append(cardModel.getDetailId()).append("','");//ID
        sql.append(cardModel.getCustId()).append("','");//`CUS_ID`-客户号
        sql.append(cardModel.getAcctId()).append("','");//`RIGHT_ACCT_ID`
        sql.append(cardModel.getRightsId()).append("','");//`RIGHTS_KINDS_ID`
        sql.append(TimeUtils.formatterDate(time)).append("','");//`ACCT_DATE`账务日期
        sql.append(cardModel.getStatus()).append("','");//`STATUS`--状态
        sql.append(cardModel.getOperId()).append("','");//`OPER_ID`--积分变动类型 积分变动类型
        sql.append(cardModel.getOperval()).append("','");//OPER_VALUE-'积分变动值'
        sql.append(cardModel.getTransFlowId()).append("','");//`TRANS_FLOW_ID`-'交易流水号'
        sql.append(cardModel.getTransAmt()).append("','");//`TRANS_AMT`-'交易金额'
        sql.append(cardModel.getTransCurrency()).append("','");//`TRANS_CURRENCY`-'交易币种'
        sql.append(cardModel.getTransDesc()).append("','");//`TRANS_DESC`-'交易描述'
        sql.append(cardModel.getOrderId()).append("','");//`ORDER_ID`-'订单号
        sql.append(cardModel.getTransDate()).append("','");//`TRANS_DATE`-'交易发生日期'
        sql.append(cardModel.getTransTime()).append("','");//`TRANS_TIME`-'交易发生时间'
        sql.append(cardModel.getCreateDate()).append("','");//`CREATE_DATE`-'创建日期'
        sql.append(cardModel.getCreateTime()).append("','");//`CREATE_TIME`-'创建时间'
        sql.append(cardModel.getUpdateDate()).append("','");//`UPDATE_DATE`-'更新日期'
        sql.append(cardModel.getUpdateTime()).append("','");//`UPDATE_TIME`-'更新时间'
//        sql.append(cardModel.getOrgCode()).append("');");//`ORG_CODE`-'机构号'
        sql.append(cardModel.getOrgCode()).append("'");//`ORG_CODE`-'机构号'

        return sql.toString();
    }
    public String generateRecordSQL(CardModel cardModel) {
//        StringBuilder sql=new StringBuilder("INSERT INTO `tbl_rights_record` VALUES ('");
        StringBuilder sql = new StringBuilder("'");
        sql.append(cardModel.getDetailId()).append("','");//ID
        sql.append(cardModel.getDetailId()).append("','");//`DETAIL_ID`----tbl_online_rights_detail->id
        sql.append(cardModel.getCustId()).append("','");//`cus_id`
        sql.append(cardModel.getAcctId()).append("','");//`RIGHT_ACCT_ID`----'Tbl_Rights_Acct-id',
        sql.append(cardModel.getRightsId()).append("','");//`RIGHTS_KINDS_ID`---权益类型ID
        sql.append(TimeUtils.formatterDate(time)).append("','");//`ACCT_DATE`账务日期
        sql.append(cardModel.getStatus()).append("0','");//`STATUS`--状态
        sql.append(cardModel.getOperId()).append("','");//`OPER_ID`--积分变动类型 积分变动类型
        sql.append(cardModel.getOperval()).append("','");//OPER_VALUE-'积分变动值'
        sql.append(cardModel.getTransFlowId()).append("','");//`TRANS_FLOW_ID`-'交易流水号'
        String nanoTime=String.valueOf(System.nanoTime());
        String  cardNo="6226"+nanoTime.substring(2);
        sql.append(cardNo).append("','");//`TRANS_CARD`---'交易卡号'--用当前时间来随机生成
        sql.append(cardModel.getTransAmt()).append("','");//`TRANS_AMT`-'交易金额'
        sql.append(cardModel.getTransDesc()).append("','");//`TRANS_DESC`-'交易描述'
        sql.append(cardModel.getOrderId()).append("','");//`ORDER_ID`-'订单号
        sql.append(cardModel.getTransDate()).append("','");//`TRANS_DATE`-'交易发生日期'
        sql.append(cardModel.getTransTime()).append("','");//`TRANS_TIME`-'交易发生时间'
        sql.append("3050").append(nanoTime).append("','");//``ACQMEMB_ID``-'收单机构会员号'
        sql.append(transSrc(cardModel.getAcctId())).append("','");//```TRANS_SRC```-'交易来源
        sql.append(cardModel.getTransCurrency()).append("','");//`TRANS_CURRENCY`-'交易币种'
        sql.append("TRANCODE").append("','");//``TRANS_CODE``-'交易代码'
        sql.append("0011").append("','");//`MER_CAT_CD`-'商户类型'
        sql.append(nanoTime.substring(6)).append("','");//`MERCH_SEQ`-商户序号-8
        sql.append("0048888000").append("','");//`ACPTOR_ID`-'收单商户编号'-32
        sql.append(campId(cardModel.getAcctId())).append("','");//``CAMP_ID``-'活动编号'-32
        sql.append(cardModel.getCreateDate()).append("','");//```START_DATE```-'发生交易时账户开始日期',
        sql.append(cardModel.getCreateTime()).append("','");//````END_DATE````-'发生交易时账户结束日期',
        sql.append(cardModel.getCreateDate()).append("','");//`CREATE_DATE`-'创建日期'
        sql.append(cardModel.getCreateTime()).append("','");//`CREATE_TIME`-'创建时间'
        sql.append(cardModel.getUpdateDate()).append("','");//`UPDATE_DATE`-'更新日期'
        sql.append(cardModel.getUpdateTime()).append("','");//`UPDATE_TIME`-'更新时间'
//        sql.append(cardModel.getOrgCode()).append("');");//`ORG_CODE`-'机构号'
        sql.append(cardModel.getOrgCode()).append("'");//`ORG_CODE`-'机构号'

        return sql.toString();
    }
    private CardModel generateEntity(int i){
        CardModel cardModel=new CardModel();

        int days = random.nextInt(1000);
        LocalDateTime endDate = time.plusDays(days);
        endDate = endDate.plusHours(random.nextInt(10));
        String ymd = TimeUtils.formatterDate(time);
        String hms = TimeUtils.formatterTime(time);

        String custId = generateNumCards(i);
        cardModel.setAcctId(i);//账户表的ID
        cardModel.setCustId(custId);
        cardModel.setDetailId(i);//详情表ID

        cardModel.setTransDate(ymd);//交易发生日期
        cardModel.setTransTime(hms);//交易发生时间
        cardModel.setCreateDate(ymd);// '创建日期',
        cardModel.setCreateTime(hms);//创建时间
        cardModel.setUpdateDate(ymd);//更新日期
        cardModel.setUpdateTime(hms);//更新时间
        cardModel.setOrgCode("0305");//机构号
        cardModel.setEndDate(TimeUtils.formatterDate(endDate));//结束日期
        return cardModel;
    }
    private CardModel generateDetailEntity(CardModel cardModel,int i){
        CardModel result=new CardModel();
        BeanUtils.copyProperties(cardModel,result);
        result.setDetailId(i);
        String ymd = TimeUtils.formatterDate(time);
        String hms = TimeUtils.formatterTime(time);
        int transAmt=random.nextInt(1000);
        result.setOperval(transAmt*10);//积分变动值
        result.setTransAmt(transAmt);//交易金额
        result.setTransFlowId("FLOW"+ymd+hms+System.nanoTime());
        result.setOrderId("ORDERID"+ymd+hms+i);
        return result;
    }
    public void generateCardsFiles(int num, String dir,int filePerSize) {

        BufferedWriter acctWriter = null;
        BufferedWriter detailWriter=null;
        BufferedWriter recordWriter=null;
        int startIndex=0;
        try {
            int fileCount = 1;
            int count = 0;
            int start=0;
            for (int i = start; i < start+num; i++) {
                if (i % filePerSize == 0) {
                    if (acctWriter != null) {
                        acctWriter.flush();acctWriter.close();
                        detailWriter.flush();detailWriter.close();
                        recordWriter.flush();recordWriter.close();
                    }
                    acctWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dir+File.separator+"sql-acct-" + fileCount + ".txt"), "UTF-8"));
                    detailWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dir+File.separator+"sql-detail-" + fileCount + ".txt"), "UTF-8"));
                    recordWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dir+File.separator+"sql-record-" + fileCount + ".txt"), "UTF-8"));
                    fileCount++;
                    count = 0;
                }
                count++;
                CardModel cardModel=generateEntity(i);


                int detailNum=random.nextInt(5)+1;
                int sumPoints=0;
                for(int k=0;k<detailNum;k++){
                    startIndex++;
                    CardModel detailModel=generateDetailEntity(cardModel,startIndex);
                    String detailSql=generateDetailSQL(detailModel);
                    String recordSql=generateRecordSQL(detailModel);
                    detailWriter.write(detailSql);detailWriter.newLine();
                    recordWriter.write(recordSql);recordWriter.newLine();
                    sumPoints+=detailModel.getOperval();
                }
                cardModel.setOperval(sumPoints);
                String acctSql=generateAcctSQL(cardModel);
                acctWriter.write(acctSql);
                acctWriter.newLine();

                if (count % 100000 == 0) {
                    acctWriter.flush();
                    detailWriter.flush();
                    recordWriter.flush();
                }
                if ((i+1) % 500000 == 0) {
                    System.out.println("执行到记录" + (i+1-start));
                }
            }
            acctWriter.flush();detailWriter.flush();recordWriter.flush();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (acctWriter != null) {
                try {
                    acctWriter.close();detailWriter.close();recordWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("详情总的记录数："+startIndex);
    }
    public static void main(String[] args) {
        CardServiceImpl service=new CardServiceImpl();
        int num=12000000;//总的记录数 TODO  80000000
        String dir="G:/sql/";
        int filePerSize = 12000000;//每个文件中的记录数 TODO
        service.generateCardsFiles(num,dir,filePerSize);

    }
}
